View Javadoc
1 /* 2 * Scope: a generic MVC framework. 3 * Copyright (c) 2000-2002, The Scope team 4 * All rights reserved. 5 * 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * Neither the name "Scope" nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 * 35 * 36 * $Id: SLabel.java,v 1.9 2002/09/13 17:04:39 ludovicc Exp $ 37 */ 38 package org.scopemvc.view.swing; 39 40 import java.beans.Beans; 41 import javax.swing.*; 42 43 import org.apache.commons.logging.Log; 44 import org.apache.commons.logging.LogFactory; 45 46 import org.scopemvc.core.Control; 47 import org.scopemvc.core.Controller; 48 import org.scopemvc.core.PropertyView; 49 import org.scopemvc.core.Selector; 50 import org.scopemvc.util.Debug; 51 import org.scopemvc.util.convertor.StringConvertor; 52 import org.scopemvc.util.convertor.StringConvertors; 53 import org.scopemvc.view.util.ModelBindable; 54 55 /*** 56 * <P> 57 * 58 * A JLabel linked to a property of a bound model object. The property must have 59 * a StringConvertor to handle conversion to and from a String representation 60 * that will be edited in the textfield. </P> <P> 61 * 62 * SLabel responds to the bound model or the particular bound property becoming 63 * read-only by disabling itself. An SLabel is also disabled if it has no bound 64 * model or property. </P> 65 * 66 * @author <A HREF="mailto:smeyfroi@users.sourceforge.net">Steve Meyfroidt</A> 67 * @author <A HREF="mailto:ludovicc@users.sourceforge.net">Ludovic Claude</A> 68 * @created June 12, 2002 69 * @version $Revision: 1.9 $ $Date: 2002/09/13 17:04:39 $ 70 */ 71 public class SLabel extends JLabel implements PropertyView, ModelBindable, Refreshable { 72 73 private static final Log LOG = LogFactory.getLog(SLabel.class); 74 75 /*** 76 * Helper to manage model to view binding. 77 */ 78 private SwingBoundModel boundModel = new SwingBoundModel(this); 79 80 /*** 81 * The StringConvertor used to convert the model property to the String 82 * representation that the user see in the label. 83 */ 84 private StringConvertor stringConvertor; 85 86 /*** 87 * If this is set, use it instead of finding a convertor to match the 88 * datatype being edited. 89 */ 90 private StringConvertor forcedStringConvertor; 91 92 93 /*** 94 * Creates a <code>SLabel</code> instance with the specified text, image, 95 * and horizontal alignment. The label is centered vertically in its display 96 * area. The text is on the trailing edge of the image. 97 * 98 * @param text The text to be displayed by the label. 99 * @param icon The image to be displayed by the label. 100 * @param horizontalAlignment One of the following constants defined in 101 * <code>SwingConstants</code>: <code>LEFT</code>, <code>CENTER</code>, 102 * <code>RIGHT</code>, <code>LEADING</code> or <code>TRAILING</code>. 103 */ 104 public SLabel(String text, Icon icon, int horizontalAlignment) { 105 super(text, icon, horizontalAlignment); 106 setEnabled(Beans.isDesignTime()); 107 } 108 109 /*** 110 * Creates a <code>SLabel</code> instance with the specified text and 111 * horizontal alignment. The label is centered vertically in its display 112 * area. 113 * 114 * @param text The text to be displayed by the label. 115 * @param horizontalAlignment One of the following constants defined in 116 * <code>SwingConstants</code>: <code>LEFT</code>, <code>CENTER</code>, 117 * <code>RIGHT</code>, <code>LEADING</code> or <code>TRAILING</code>. 118 */ 119 public SLabel(String text, int horizontalAlignment) { 120 this(text, null, horizontalAlignment); 121 } 122 123 /*** 124 * Creates a <code>SLabel</code> instance with the specified text. The label 125 * is aligned against the leading edge of its display area, and centered 126 * vertically. 127 * 128 * @param text The text to be displayed by the label. 129 */ 130 public SLabel(String text) { 131 this(text, null, LEADING); 132 } 133 134 /*** 135 * Creates a <code>SLabel</code> instance with the specified image and 136 * horizontal alignment. The label is centered vertically in its display 137 * area. 138 * 139 * @param horizontalAlignment One of the following constants defined in 140 * <code>SwingConstants</code>: <code>LEFT</code>, <code>CENTER</code>, 141 * <code>RIGHT</code>, <code>LEADING</code> or <code>TRAILING</code>. 142 * @param image Description of the Parameter 143 */ 144 public SLabel(Icon image, int horizontalAlignment) { 145 this(null, image, horizontalAlignment); 146 } 147 148 /*** 149 * Creates a <code>SLabel</code> instance with the specified image. The 150 * label is centered vertically and horizontally in its display area. 151 * 152 * @param image Description of the Parameter 153 */ 154 public SLabel(Icon image) { 155 this(null, image, CENTER); 156 } 157 158 /*** 159 * Creates a <code>SLabel</code> instance with no image and with an empty 160 * string for the title. The label is centered vertically in its display 161 * area. The label's contents, once set, will be displayed on the leading 162 * edge of the label's display area. 163 */ 164 public SLabel() { 165 this("", null, LEADING); 166 } 167 168 169 // ------------------- Delegate to BoundModel ------------------- 170 171 /*** 172 * Gets the bound model 173 * 174 * @return The boundModel value 175 */ 176 public final Object getBoundModel() { 177 return boundModel.getBoundModel(); 178 } 179 180 181 /*** 182 * Gets the selector 183 * 184 * @return The selector value 185 */ 186 public final Selector getSelector() { 187 return boundModel.getSelector(); 188 } 189 190 191 /*** 192 * Don't assign a Controller to STextField, instead delegate to the 193 * containing SwingView that has a parent Controller. 194 * 195 * @return The controller value 196 */ 197 public Controller getController() { 198 return null; 199 } 200 201 202 /*** 203 * SLabel don't issue any control 204 * 205 * @param inControl Description of the Parameter 206 */ 207 public void issueControl(Control inControl) { 208 throw new UnsupportedOperationException("Can't issue a control from a SLabel"); 209 } 210 211 /*** 212 * Get the current value (what would be set as a property of the bound model 213 * object) being presented on the View. 214 * 215 * @return property value from parsing the textfield's current String 216 * representation. 217 * @exception IllegalArgumentException if the conversion from String fails. 218 */ 219 public Object getViewValue() throws IllegalArgumentException { 220 String text = getText(); 221 222 if (stringConvertor == null) { 223 return null; 224 } 225 226 return stringConvertor.stringAsValue(text); 227 } 228 229 230 /*** 231 * Sets the bound model 232 * 233 * @param inModel The new boundModel value 234 */ 235 public final void setBoundModel(Object inModel) { 236 boundModel.setBoundModel(inModel); 237 setupStringConvertor(); 238 } 239 240 241 /*** 242 * Sets the selector 243 * 244 * @param inSelector The new selector value 245 */ 246 public final void setSelector(Selector inSelector) { 247 boundModel.setSelector(inSelector); 248 setupStringConvertor(); 249 } 250 251 252 /*** 253 * Sets the selector string 254 * 255 * @param inSelectorString The new selectorString value 256 */ 257 public final void setSelectorString(String inSelectorString) { 258 boundModel.setSelectorString(inSelectorString); 259 setupStringConvertor(); 260 } 261 262 /*** 263 * Don't assign a Controller to this component, instead delegate to the 264 * containing SwingView that has a parent Controller. 265 * 266 * @param inController The new controller value 267 */ 268 public void setController(Controller inController) { 269 throw new UnsupportedOperationException("Can't assign a Controller to a " + getClass()); 270 } 271 272 /*** 273 * Force use of this StringConvertor instead of automatically finding one to 274 * match the datatype being edited. 275 * 276 * @param inConvertor The new stringConvertor value 277 */ 278 public void setStringConvertor(StringConvertor inConvertor) { 279 forcedStringConvertor = inConvertor; 280 } 281 282 283 /*** 284 * Override to call super.setText() only if new value not equals() old 285 * value. 286 * 287 * @param t new text. 288 */ 289 public void setText(String t) { 290 if (Debug.ON) { 291 Debug.assertTrue(getText() != null, "null getText()"); 292 } 293 if (!getText().equals(t)) { 294 super.setText(t); 295 } 296 } 297 298 // --------------------- Implement ModelBindable ---------------------- 299 300 /*** 301 * Converts the incoming value to a String via appropriate {@link 302 * org.scopemvc.util.convertor.StringConvertor}. For incoming null either 303 * disable field or set text to empty String. 304 * 305 * @param inValue Description of the Parameter 306 * @param inReadOnly Description of the Parameter 307 */ 308 public void updateFromProperty(Object inValue, boolean inReadOnly) { 309 if (LOG.isDebugEnabled()) { 310 LOG.debug("updateFromProperty: " + inValue + ", " + inReadOnly); 311 } 312 313 // ***** Hack. Need to revisit PropertyManager to traverse nulls and use metadata etc 314 setupStringConvertor(); 315 316 if (stringConvertor == null) { 317 setEnabled(false); 318 setText(""); 319 } else if (inValue == null) { 320 setEnabled(true); 321 setText(""); 322 } else { 323 324 setEnabled(!inReadOnly); 325 try { 326 String text = stringConvertor.valueAsString(inValue); 327 setText(text); 328 } catch (IllegalArgumentException e) { 329 // should never happen normally -- comes from getValue() but the 330 // ... property value must always be convertible to String? 331 LOG.error("updateFromProperty", e); 332 setEnabled(false); 333 } 334 } 335 revalidate(); 336 } 337 338 /*** 339 * Makes no sense. 340 * 341 * @param inException TODO: Describe the Parameter 342 */ 343 public void validationFailed(Exception inException) { 344 // noop 345 } 346 347 348 /*** 349 * Makes no sense. 350 */ 351 public void validationSuccess() { 352 // noop 353 } 354 355 356 // ------------------ Refreshable ------------------------- 357 358 /*** 359 * Description of the Method 360 */ 361 public void refresh() { 362 Object propertyValue = boundModel.getPropertyValue(); 363 boolean propertyReadOnly = boundModel.getPropertyReadOnly(); 364 updateFromProperty(propertyValue, propertyReadOnly); 365 } 366 367 368 /*** 369 * Description of the Method 370 */ 371 protected void setupStringConvertor() { 372 if (forcedStringConvertor != null) { 373 stringConvertor = forcedStringConvertor; 374 return; 375 } 376 377 try { 378 Object m = getBoundModel(); 379 Selector s = getSelector(); 380 if (m != null) { 381 Class clazz = boundModel.getPropertyManager().getPropertyClass(m, s); 382 stringConvertor = StringConvertors.forClass(clazz); 383 } 384 } catch (Exception e) { 385 stringConvertor = null; 386 } 387 } 388 389 } 390

This page was automatically generated by Maven